// package main
//
// import (
//
//	"bufio"
//	"context"
//	"flag"
//	"fmt"
//	"io"
//	"log"
//	"os"
//	"strings"
//	"time"
//
//	"hello_client/pb"
//
//	"google.golang.org/grpc"
//	"google.golang.org/grpc/credentials/insecure"
//
// )
//
// // hello_client
//
// const (
//
//	defaultName = "world"
//
// )
//
// var (
//
//	addr = flag.String("addr", "127.0.0.1:8972", "the address to connect to")
//	name = flag.String("name", defaultName, "Name to greet")
//
// )
//
//	func simpleRpc(err error, c pb.GreeterClient) {
//		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
//		defer cancel()
//		r, err := c.SayHello(ctx, &pb.HelloRequest{Name: *name})
//		if err != nil {
//			log.Fatalf("could not greet: %v", err)
//		}
//		log.Printf("Greeting: %s", r.GetReply())
//	}
//
//	func runServerStreamRpc(c pb.GreeterClient) {
//		// server端流式RPC
//		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
//		defer cancel()
//		stream, err := c.LotsOfReplies(ctx, &pb.HelloRequest{Name: *name})
//		if err != nil {
//			log.Fatalf("c.LotsOfReplies failed, err: %v", err)
//		}
//		for {
//			// 接收服务端返回的流式数据，当收到io.EOF或错误时退出
//			res, err := stream.Recv()
//			if err == io.EOF {
//				break
//			}
//			if err != nil {
//				log.Fatalf("c.LotsOfReplies failed, err: %v", err)
//			}
//			log.Printf("got reply: %q\n", res.GetReply())
//			log.Println("休息一下")
//			time.Sleep(2 * time.Second)
//		}
//	}
//
//	func runClientStreamRpc(c pb.GreeterClient) {
//		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
//		defer cancel()
//		// 客户端流式RPC
//		stream, err := c.LotsOfGreetings(ctx)
//		if err != nil {
//			log.Fatalf("c.LotsOfGreetings failed, err: %v", err)
//		}
//		names := []string{"七米", "q1mi", "沙河娜扎"}
//		for _, name := range names {
//			// 发送流式数据
//			err := stream.Send(&pb.HelloRequest{Name: name})
//			if err != nil {
//				log.Fatalf("c.LotsOfGreetings stream.Send(%v) failed, err: %v", name, err)
//			}
//		}
//		res, err := stream.CloseAndRecv()
//		if err != nil {
//			log.Fatalf("c.LotsOfGreetings failed: %v", err)
//		}
//		log.Printf("got reply: %v", res.GetReply())
//	}
//
//	func runServerAndClientStreamRpc(c pb.GreeterClient) {
//		ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
//		defer cancel()
//		// 双向流模式
//		stream, err := c.BidiHello(ctx)
//		if err != nil {
//			log.Fatalf("c.BidiHello failed, err: %v", err)
//		}
//		waitc := make(chan struct{})
//		go func() {
//			for {
//				// 接收服务端返回的响应
//				in, err := stream.Recv()
//				if err == io.EOF {
//					// read done.
//					close(waitc)
//					return
//				}
//				if err != nil {
//					log.Fatalf("c.BidiHello stream.Recv() failed, err: %v", err)
//				}
//				fmt.Printf("AI：%s\n", in.GetReply())
//			}
//		}()
//		// 从标准输入获取用户输入
//		reader := bufio.NewReader(os.Stdin) // 从标准输入生成读对象
//		for {
//			cmd, _ := reader.ReadString('\n') // 读到换行
//			cmd = strings.TrimSpace(cmd)
//			if len(cmd) == 0 {
//				continue
//			}
//			if strings.ToUpper(cmd) == "QUIT" {
//				break
//			}
//			// 将获取到的数据发送至服务端
//			if err := stream.Send(&pb.HelloRequest{Name: cmd}); err != nil {
//				log.Fatalf("c.BidiHello stream.Send(%v) failed: %v", cmd, err)
//			}
//		}
//		stream.CloseSend()
//		<-waitc
//	}
//
//	func main() {
//		flag.Parse()
//		// 连接到server端，此处禁用安全传输
//		conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
//		if err != nil {
//			log.Fatalf("did not connect: %v", err)
//		}
//		//后置处理:断开连接
//		defer conn.Close()
//		c := pb.NewGreeterClient(conn)
//
//		// 执行RPC调用并打印收到的响应数据
//		//simpleRpc(err, c)
//		//runServerStreamRpc(c)
//		//runClientStreamRpc(c)
//		runServerAndClientStreamRpc(c)
//	}
package main

import (
	"context"
	"flag"
	"fmt"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/status"
	"hello_client/pb"
	"log"
	"time"

	"google.golang.org/genproto/googleapis/rpc/errdetails"
	"google.golang.org/grpc"
)

// grpc 客户端
// 调用server端的 SayHello 方法

var name = flag.String("name", "七米", "通过-name告诉server你是谁")

func main() {

	// 因为这里使用的是自签名的证书，信任链缺失，因此需要客户端手动配置信任该证书
	ca, err := credentials.NewClientTLSFromFile("ca/server.crt",
		"")
	if err != nil {
		log.Fatalf("Failed to load certificates: %v", err)
	}

	// 创建 gRPC 连接
	conn, err := grpc.Dial("127.0.0.1:8972", grpc.WithTransportCredentials(ca))

	//// 连接server
	//conn, err := grpc.Dial("127.0.0.1:8972", grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatalf("grpc.Dial failed,err:%v", err)
		return
	}
	defer conn.Close()
	// 创建客户端
	c := pb.NewGreeterClient(conn) // 使用生成的Go代码
	// 调用RPC方法
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	resp, err := c.SayHello(ctx, &pb.HelloRequest{Name: *name})
	if err != nil {
		s := status.Convert(err)        // 将err转为status
		for _, d := range s.Details() { // 获取details
			switch info := d.(type) {
			case *errdetails.QuotaFailure:
				fmt.Printf("Quota failure: %s\n", info)
			default:
				fmt.Printf("Unexpected type: %s\n", info)
			}
		}
		fmt.Printf("c.SayHello failed, err:%v\n", err)
		return
	}
	// 拿到了RPC响应
	log.Printf("resp:%v\n", resp.GetReply())
}
